package com.everspring.util;

import com.lowagie.text.DocumentException;
import com.lowagie.text.pdf.AcroFields;
import com.lowagie.text.pdf.BaseFont;
import com.lowagie.text.pdf.PdfReader;
import com.lowagie.text.pdf.PdfStamper;
import lombok.extern.slf4j.Slf4j;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import static com.everspring.constants.PdfCommonConstants.DEFAULT_ENCODING;

/**
 * pdf表单域工具类
 *
 * @author EverSpring
 */
@Slf4j
public class PdfAcroUtils extends PdfWrapper{

    /**
     * 填充表单域模版PDF，生成新的PDF文档
     *
     * @param templatePdfPath 模板pdf路径
     * @param data            pdf文件byte数组
     */
    public static byte[] export(String templatePdfPath, Map<String, String> data) throws IOException {
        try (ByteArrayOutputStream bos = new ByteArrayOutputStream();) {
            PdfReader reader = new PdfReader(templatePdfPath);
            /* 将要生成的目标PDF文件名称 */
            PdfStamper ps = new PdfStamper(reader, bos);
            /* 使用中文字体 */
            BaseFont bf = BaseFont.createFont(getFontName(), DEFAULT_ENCODING, BaseFont.NOT_EMBEDDED);

            ArrayList<BaseFont> fontList = new ArrayList<>();
            fontList.add(bf);
            /* 取出报表模板中的所有字段 */
            AcroFields fields = ps.getAcroFields();
            fields.setAllSubstitutionFonts(fontList);
            fillData(fields, data);
            /* 必须要调用这个，否则文档不会生成的  如果为false那么生成的PDF文件还能编辑，一定要设为true*/
            ps.setFormFlattening(true);
            ps.close();
            return bos.toByteArray();
        } catch (Exception e) {
            log.error("表单域方式生成pdf异常", e);
            throw e;
        }
    }

    /**
     * 填充表单域
     *
     * @param fields 表单域集合
     * @param data   数据
     * @throws IOException
     * @throws DocumentException
     */
    private static void fillData(AcroFields fields, Map<String, String> data) throws IOException, DocumentException {
        List<String> keys = new ArrayList<>();
        Map<String, AcroFields.Item> formFields = fields.getAllFields();
        for (Map.Entry<String, String> entry : data.entrySet()) {
            String key = entry.getKey();
            if (formFields.containsKey(key)) {
                // 为字段赋值,注意字段名称是区分大小写的
                fields.setField(key, entry.getValue());
                keys.add(key);
            }
        }
        Iterator<String> itemsKey = formFields.keySet().iterator();
        while (itemsKey.hasNext()) {
            String itemKey = itemsKey.next();
            if (!keys.contains(itemKey)) {
                fields.setField(itemKey, " ");
            }
        }
    }

}
